package org.azj.dbOperatorComponent;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Set;

public class CompositeTable extends AbsComposibleTable
{
	String schemaName;
	String tableName;
	
	// inner tables
	List<IDbQueryOperation> innerTables;
	String joinStatement;
	
	public CompositeTable(String schema, String tableName) {
		this.schemaName = schema;
		this.tableName = tableName;
		
		innerTables = new ArrayList<IDbQueryOperation>();
		joinStatement = "";
	}
	
	@Override
	public void addComponentTable(
			IDbQueryOperation componentTable,
			JoinType joinType, String onFilter)
	{		
		// if the input table is the first one, then ignore the join statement
		boolean ignoreJoin = innerTables.size() == 0;
		innerTables.add(componentTable);
		
		String tableName = innerTables.get(innerTables.size() - 1).getTableFullName();
		
		if (ignoreJoin == false)
		{
			joinStatement += 
					" " + joinType.toString() + " " + tableName + " ON " + onFilter + " ";
		}
		else
		{
			joinStatement += tableName;	
		}
	}
	
	@Override
	public HashMap<String, IBasicTableOperation> getComponentTables() 
	{
		HashMap<String, IBasicTableOperation> resultHashMap = 
				new HashMap<String, IBasicTableOperation>();
		
		for (IBasicTableOperation table : innerTables) {
			resultHashMap.put(table.getTableFullName(), table);
		}
		
		return resultHashMap;
	}

	@Override
	public String getJoinOnFilters() {
		return joinStatement;
	}

	@Override
	public ICommand getSelectCommand(SelectFilter selectFilter) {
		// get all inner join pattern string 
		// that appears in the FROM clause
		String tableNameOfCompositeString = this.getJoinOnFilters();
		return super.setSelectFilter(selectFilter, tableNameOfCompositeString);
	}

	@Override
	public String GetTableSchema() {
		return schemaName;
	}

	@Override
	public String getTableName() {
		return tableName;
	}

	@Override
	public String getTableFullName() {
		return String.format("%s.%s", schemaName, tableName);
	}

	@Override
	public String getTableType() throws SQLException {
		return "composite table";
	}

	@Override
	public HashMap<String, IColumnProperty> getAllColumns() throws SQLException {
		HashMap<String, IColumnProperty> result = new HashMap<String, IColumnProperty>();
		
		HashMap<String, IBasicTableOperation> tablesMap = this.getComponentTables();
		Set<String> tableNamesSet = tablesMap.keySet();
		
		// for each table copy its columns
		for (String tableName : tableNamesSet) {
			IBasicTableOperation table = tablesMap.get(tableName);
			result.putAll(table.getAllColumns());
		}
		
		return result;
	}

	@Override
	public IColumnProperty getColumn(String columnName) throws SQLException {
		HashMap<String, IBasicTableOperation> tablesMap = this.getComponentTables();
		Set<String> tableNamesSet = tablesMap.keySet();
		
		IColumnProperty columnProperty = null;
		for (String tableName : tableNamesSet) 
		{
			IBasicTableOperation table = tablesMap.get(tableName);
			columnProperty = table.getColumn(columnName);
			if (columnProperty != null)
			{
				break;
			}
		}
		
		return columnProperty;
	}

	@Override
	public HashMap<String, IColumnProperty> getPrimaryKey() throws SQLException {
		return null;
	}

	@Override
	public List<List<IForeignKeyColumnProperty>> getForeignKey()
			throws SQLException {
		return null;
	}
}
